package com.ckx.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.ckx.constants.SystemConstants;
import com.ckx.domain.dto.RoleAddDto;
import com.ckx.domain.dto.RoleDto;
import com.ckx.domain.dto.RoleUpdateDto;
import com.ckx.domain.entity.RoleMenu;
import com.ckx.domain.vo.PageVo;
import com.ckx.domain.vo.RoleVo;
import com.ckx.enums.AppHttpCodeEnum;
import com.ckx.exception.SystemException;
import com.ckx.mapper.RoleMapper;
import com.ckx.service.RoleMenuService;
import com.ckx.service.RoleService;
import com.ckx.domain.entity.Role;
import com.ckx.utils.BeanCopyUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 角色信息表(Role)表服务实现类
 *
 * @author makejava
 * @since 2023-08-01 17:27:47
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {

    @Autowired
    private RoleMenuService roleMenuService;

    @Override
    public List<String> selectRoleKeyByUserId(Long userId) {

        if (SystemConstants.ADMAIN.equals(userId)) {
            List<String> roles = new ArrayList<>();
            roles.add("admin");
            return roles;
        }

        return this.getBaseMapper().selectRoleKeyByUserId(userId);

    }

    @Override
    public PageVo selectByPage(Integer pageNum, Integer pageSize, Role role) {

        QueryWrapper<Role> wrapper = new QueryWrapper<>();
        wrapper.lambda().like(StringUtils.hasText(role.getRoleName()), Role::getRoleName, role.getRoleName());
        wrapper.lambda().eq(StringUtils.hasText(role.getStatus()), Role::getStatus, role.getStatus());
        wrapper.lambda().orderByAsc(Role::getRoleSort);
        Page<Role> page = new Page<>(pageNum, pageSize);
        Page<Role> rolePage = page(page, wrapper);

        List<RoleVo> roleVos = rolePage.getRecords().stream()
                .map(r -> BeanCopyUtil.copyBean(r, RoleVo.class))
                .collect(Collectors.toList());

        return new PageVo(roleVos, page.getTotal());

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addRole(RoleAddDto roleAddDto) {
        Role role = BeanCopyUtil.copyBean(roleAddDto, Role.class);
        //存储角色
        if (this.save(role)) {
            //存储角色与权限关联
            Long[] menuIds = roleAddDto.getMenuIds();
            List<RoleMenu> roleMenus = new ArrayList<>();
            for (Long menuId : menuIds) {
                roleMenus.add(new RoleMenu(role.getId(), menuId));
            }
            roleMenuService.saveBatch(roleMenus);
        }
    }

    @Override
    public void changeStatus(RoleDto roleDto) {
        UpdateWrapper<Role> wrapper = new UpdateWrapper<>();
        wrapper.lambda().set(Role::getStatus, roleDto.getStatus());
        wrapper.lambda().eq(Role::getId, roleDto.getRoleId());
        this.update(wrapper);
    }

    @Override
    public Role getRoleInfo(Long id) {
        if (id == null || id <= 0) {
            throw new SystemException(AppHttpCodeEnum.ARGS_FAIL);
        }
        return this.getById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateRole(RoleUpdateDto roleUpdateDto) {

        //更新角色
        Role role = BeanCopyUtil.copyBean(roleUpdateDto, Role.class);
        if (this.updateById(role)) {
            //更新关联表
            //先删除
            QueryWrapper<RoleMenu> wrapper = new QueryWrapper<>();
            wrapper.lambda().eq(RoleMenu::getRoleId, role.getId());
            roleMenuService.remove(wrapper);
            //后插入
            List<Long> menuIds = roleUpdateDto.getMenuIds();

            List<RoleMenu> roleMenuList = menuIds.stream()
                    .map(menuId -> new RoleMenu(role.getId(), menuId))
                    .collect(Collectors.toList());
            roleMenuService.saveBatch(roleMenuList);
        }

    }

    @Override
    public void del4DelFlag(Long id) {
        UpdateWrapper<Role> wrapper = new UpdateWrapper<>();
        wrapper.lambda().set(Role::getDelFlag, SystemConstants.DELFLAG);
        wrapper.lambda().eq(Role::getId, id);
        this.update(wrapper);
    }

    @Override
    public List<RoleVo> listAllRole() {
        List<Role> roles = this.getBaseMapper().selectList(new QueryWrapper<Role>());
        return roles.stream()
                .map(role -> BeanCopyUtil.copyBean(role, RoleVo.class))
                .collect(Collectors.toList());
    }
}

